package com.ys.controller.web.sys;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;

import com.alibaba.fastjson.JSONObject;
import com.bo.enume.sys.StatusEnum;
import com.ys.config.ImportConfig;
import com.ys.config.MyConfig;
import com.ys.entity.shiro.LoginUser;
import com.ys.entity.sys.TsUserInfo;
import com.ys.entity.sys.YsCol;
import com.ys.entity.sys.YsMenu;
import com.ys.entity.sys.YsProcInst;
import com.ys.enume.flow.YsProcInstEnum;
import com.ys.enume.flow.YspTaskAuditUserEnum;
import com.ys.enume.sys.YsColEnum;
import com.ys.enume.sys.YsMenuEnum;
import com.ys.service.sys.CommonService;
import com.ys.service.sys.ImgcodeService;
import com.ys.util.shiro.ShiroUtils;
import com.ys.vo.W;

import lombok.AllArgsConstructor;
import lombok.Data;

@CrossOrigin
@Controller
public class WebController {
	
	@Autowired
	private CommonService commonService;
    @Autowired
    private ImgcodeService imgcodeService;
	
	
	/**
	 * 登录登出页
	 */
	@GetMapping({"/login", "/logout"})
	public String login(Model model){
		
		Subject subject = SecurityUtils.getSubject();
		if (subject != null) {
			subject.logout();
		}
		return "login";
	}
	
	
	/**
	 * 示例页
	 */
	@GetMapping("/demo")
	public String demo(Model model){
		return "demo";
	}
	
	
	/**
	 * 导入页
	 */
	@GetMapping("/toImport")
	public String toImport(Model model, Long menuId){
		
		if (menuId == null) {
			return W.error(model, "菜单ID不能为空");
		} else if (!ImportConfig.ID_FILENAME_MAP.containsKey(menuId)) {
			return W.error(model, "该菜单尚未配置生成路径");
		}
		
		List<YsCol> listYsCol = new YsCol().setMenuId(menuId).setImportState(YsColEnum.ImportState.YES.value)
				.setOrderby("A.ImportSortNo asc")
				.queryList();
		JSONObject nameValMap = new JSONObject();
		List<ImportConfigDto.FieldDto> fieldArr = new ArrayList<ImportConfigDto.FieldDto>();
		for(YsCol entity : listYsCol) {
			String code = entity.getCode();
			String name = entity.getName();
			nameValMap.put(name, code);
			fieldArr.add(new ImportConfigDto.FieldDto(code, name));
		}
		
		String fileName = ImportConfig.ID_FILENAME_MAP.get(menuId) + ".xlsx";
		ImportConfigDto dto = new ImportConfigDto(menuId, nameValMap, fileName, fieldArr);
		model.addAttribute("dto", dto);
		return "sys/common2/toImport";
	}
	@Data
	@AllArgsConstructor
	public static class ImportConfigDto{
		private Long menuId; // 菜单ID
		private JSONObject nameValMap;
		private String fileName; // 模板文件名称
		private List<FieldDto> fieldArr;
		
		@Data
		@AllArgsConstructor
		public static class FieldDto{
			private String code; // 字段编码
			private String name; // 字段名称
		}
		
	}
	
	/**
	 * 首页
	 */
	@GetMapping({ "", "/", "/index" })
	public String index(Model model){
		
		LoginUser loginUser = ShiroUtils.getLoginUser();
		if (loginUser == null) {
			
			Subject subject = SecurityUtils.getSubject();
			if (subject != null) {
				subject.logout();
			}
			return "login";
		}
		Long roleId = loginUser.getRoleId();
		
		// 顶部菜单数组
		List<YsMenu> listMenuOne = new YsMenu().setStatus(StatusEnum.ON_USED.value)
				.setLev(YsMenuEnum.Lev.ONE.value)
				.setOrderby("A.SortNo asc")
				.queryList();
		List<YsMenu> listMenuTwo = new YsMenu().setStatus(StatusEnum.ON_USED.value)
				.setLev(YsMenuEnum.Lev.TWO.value)
				.setOrderby("A.SortNo asc")
				.queryList();
		List<YsMenu> listMenuThree = new YsMenu().setStatus(StatusEnum.ON_USED.value)
				.setLev(YsMenuEnum.Lev.THREE.value)
				.setOrderby("A.SortNo asc")
				.where(roleId.longValue() != 1L ? "A.Id in (select MenuId from YS_RoleMenu where RoleId = '" + roleId + "')" : "1=1")
				.queryList();
		
		// 搜索菜单数组
		List<IndexDto.SearchMenuDto> searchMenuArr = new ArrayList<IndexDto.SearchMenuDto>();

		// 一级菜单数组
		List<IndexDto.MenuDto> menuOneArr = new ArrayList<IndexDto.MenuDto>();
		for(YsMenu ysMenu1 : listMenuOne) {
			
			// 正式环境移除【开发】大模块
			if ("pro".equals(MyConfig.getActive()) && ysMenu1.getId().longValue() == 10L) {
				continue;
			}
			
			List<IndexDto.MenuDto.SubDto> menuTwoArr = new ArrayList<IndexDto.MenuDto.SubDto>();
			
			// 添加二级菜单
			for(YsMenu ysMenu2 : listMenuTwo) {
				if (ysMenu2.getPid().longValue() != ysMenu1.getId().longValue()) {
					continue;
				} else {
					// 添加三级菜单
					List<IndexDto.MenuDto.SubDto.ModuleDto> menuThreeArr = new ArrayList<IndexDto.MenuDto.SubDto.ModuleDto>();
					for(YsMenu ysMenu3 : listMenuThree) {
						if (ysMenu3.getPid().longValue() != ysMenu2.getId().longValue()) {
							continue;
						}
						Long id = ysMenu3.getId();
						String name = ysMenu3.getName();
						String linkTo = "/indexCommonOfMenu?menuId=" + ysMenu3.getId();
						menuThreeArr.add(new IndexDto.MenuDto.SubDto.ModuleDto(id, name, linkTo));
						
						
						searchMenuArr.add(new IndexDto.SearchMenuDto(id, name, linkTo));
					}
					if (menuThreeArr.size() == 0) {
						continue;
					}
					Long id = ysMenu2.getId();
					String name = ysMenu2.getName();
					menuTwoArr.add(new IndexDto.MenuDto.SubDto(id, name, menuThreeArr));
				}
			}
			
			if (menuTwoArr.size() == 0) {
				continue;
			}
			Long id = ysMenu1.getId();
			String name = ysMenu1.getName();
			menuOneArr.add(new IndexDto.MenuDto(id, name, menuTwoArr));
		}
		
		IndexDto.OrgDto org = null;
		
		// 当前登录的运营公司
		String operateOrgName = ShiroUtils.getOperateOrgName();
		IndexDto.OperateOrgDto operateCompany = new IndexDto.OperateOrgDto(operateOrgName);
		
		String basePath = MyConfig.getUrlDomain();
		String websocktPre = basePath.startsWith("https") ? "wss" : "ws";
		String roleName = loginUser.getRoleName();
		IndexDto.UserInfoDto userInfo = new IndexDto.UserInfoDto(loginUser.getUserId(), loginUser.getUserName(), roleName, websocktPre, basePath);
		
		String loginUserId = ShiroUtils.getUserId();
		// 待处理任务数
		Integer numTaskNeedHandle = new YsProcInst().setStatus(1).setStateFlow(YsProcInstEnum.StateFlow.PROCESS.value)
				.where("A.TaskId in (select TaskId from YSP_TaskAuditUser where UserId = '" + loginUserId + "' and State = " + YspTaskAuditUserEnum.State.FOR_AUDIT.value + ")")
				.count()
				+
				new YsProcInst().setStatus(1).setStateFlow(YsProcInstEnum.StateFlow.INIT.value)
				.setCreateUserId(loginUserId).count();
		IndexDto dto = new IndexDto(menuOneArr, org, operateCompany, userInfo, numTaskNeedHandle, searchMenuArr);
		model.addAttribute("dto", dto);


		if (!"dev".equals(MyConfig.getActive()) && !"test".equals(MyConfig.getActive()) && !"pro".equals(MyConfig.getActive())) {
			return "sys/common2/index";
		} else {
			return "sys/index";
		}
	}
	
	@Data
	@AllArgsConstructor
	public static class IndexDto {
		private List<MenuDto> menuLeftArr; // 左边菜单数组
		private OrgDto org;
		private OperateOrgDto operateOrg;
		private UserInfoDto userInfo;
		private Integer numTaskNeedHandle; // 待处理任务数
		private List<SearchMenuDto> searchMenuArr; // 搜索菜单数组

		@Data
		@AllArgsConstructor
		public static class SearchMenuDto {
			private Long id; // 菜单ID
			private String name; // 菜单名称
			private String linkTo; // 跳转链接
		}

		@Data
		@AllArgsConstructor
		public static class MenuDto {
			private Long id; // 菜单ID
			private String name; // 菜单名称
			private List<SubDto> subArr; // 二级菜单数组

			@Data
			@AllArgsConstructor
			public static class SubDto {
				private Long id; // 菜单ID
				private String name; // 菜单名称
				private List<ModuleDto> moduleArr; // 模块数组

				@Data
				@AllArgsConstructor
				public static class ModuleDto {
					private Long id; // 菜单ID
					private String name; // 菜单名称
					private String linkTo; // 跳转链接
				}
			}
		}

		@Data
		@AllArgsConstructor
		public static class OrgDto {
			private String name; // 部门名称
			private List<ItemDto> itemArr; // 部门数组

			@Data
			@AllArgsConstructor
			public static class ItemDto {
				private String name; // 部门名称
				private String orgId; // 部门ID
			}
		}

		@Data
		@AllArgsConstructor
		public static class OperateOrgDto {
			private String name; // 运营机构名称
		}

		@Data
		@AllArgsConstructor
		public static class UserInfoDto {
			private String userId; // 用户ID
			private String userName; // 用户名称
			private String roleName; // 角色名称
			private String websocktPre; // websockt开头，wss或ws
			private String basePath;
		}
	}

	/*
	 * 仪表盘
	 */
	@RequiresPermissions("sys:dashboard")
	@GetMapping("/dashboard")
	public String dashboard(Model model) {

		List<String> oneArr = new ArrayList<String>();
		{
			String str = "XX总数：--";
			oneArr.add(str);
		}
		{
			String str = "XX总数：--";
			oneArr.add(str);
		}
		
		DashboardIndexDto dto = new DashboardIndexDto(oneArr);
    	
		model.addAttribute("dto", dto);
		return "dashboard";
	}
	
	@Data
	@AllArgsConstructor
	public static class DashboardIndexDto {
		private List<String> oneArr; // 汇总
	}

	/**
	 * 通用菜单首页
	 * @param model
	 * @param request
	 * @param menuId
	 * @param loginName
	 * @param pass
	 * @param _condFields 格式： c1|c2|c3
	 * @param _condValues 格式： v1|v2|v3
	 * @return
	 */
	@GetMapping("/indexCommonOfMenu")
	public String indexCommonOfMenu(Model model, HttpServletRequest request, Long menuId,
			String loginName,
			String pass,
			String _condFields,
			String _condValues) {
		
		String loginUserId = ShiroUtils.getUserId();
		if (loginUserId == null || loginUserId.length() == 0) {
			if (loginName != null && loginName.length() > 0 && pass != null && pass.length() > 0) {

				TsUserInfo tsUserInfo = new TsUserInfo().setUserId(loginName).setUserPassWord(pass).queryFirst();
				if (tsUserInfo != null) {
					imgcodeService.doAuthAfterLogin(tsUserInfo);
				}
			} else {
				return "/login";
			}
		} else {
			if (loginName != null && loginName.length() > 0 && pass != null && pass.length() > 0 && !loginUserId.equals(loginName)) {

				TsUserInfo tsUserInfo = new TsUserInfo().setUserId(loginName).setUserPassWord(pass).queryFirst();
				if (tsUserInfo != null) {
					imgcodeService.doAuthAfterLogin(tsUserInfo);
				}
			}
		}

		Map<String, String> initCondCodeValue = new HashMap<String, String>();
		if (_condFields != null && _condFields.length() > 0 && _condValues != null && _condValues.length() > 0) {
			
			String[] _condFieldArr = _condFields.split("_yyss_");
			String[] _condValueArr = _condValues.split("_yyss_");
			
			if (_condFieldArr.length != _condValueArr.length) {
				return W.error(model, "跳转 参数有误");
			}
			for (int i = 0; i < _condFieldArr.length; i++) {
				initCondCodeValue.put(_condFieldArr[i], _condValueArr[i]);
			}
		}
		
		YsMenu ysMenu = new YsMenu().setId(menuId).queryFirst();

		// 生产环境隐藏开发菜单
		Integer count = new YsMenu().where("A.Pid in (select id from YS_Menu where Pid = 10)")
				.setId(menuId)
				.count();
		if (!"dev".equals(MyConfig.getActive()) &&!"test".equals(MyConfig.getActive()) && !"pro".equals(MyConfig.getActive()) && count == 0 && !ysMenu.getTempletType().equals(YsMenuEnum.TempletType.SELF_DEFINE.value)) {
			return commonService.indexCommonOfMenuBS(model, request, menuId, initCondCodeValue);
		} else {
			return commonService.indexCommonOfMenu(model, request, menuId, initCondCodeValue);
		}
	}

	/*
	 * 导入页面
	 */
	@GetMapping("/importCommon")
	public String importCommon(Model model, HttpServletRequest request,
			Long menuId) {
		
		ImportCommonDto dto = new ImportCommonDto(menuId);
		model.addAttribute("dto", dto);
		return "sys/common/import_common";
	}
	@Data
	@AllArgsConstructor
	public class ImportCommonDto {
		private Long menuId;
	}
}
